/**
 * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.babble.manage.service.impl;

import com.babble.manage.entity.Img;
import com.babble.manage.entity.OssFile;
import com.babble.manage.mapper.ImgMapper;
import com.babble.manage.service.IImgService;
import com.babble.manage.service.ResourceService;
import com.babble.manage.vo.ImgVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springblade.common.constant.CommonConstant;
import org.springblade.common.entity.MinioPolicy;
import org.springblade.common.enums.CodeMsg;
import org.springblade.common.exception.MsgException;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

/**
 * 图片表 服务实现类
 *
 * @author Blade
 * @since 2021-11-21
 */
@RequiredArgsConstructor
@Service
public class ImgServiceImpl extends ServiceImpl<ImgMapper, Img> implements IImgService {
	private final ExecutorService executor;
	private final ResourceService resourceService;


	@Override
	public IPage<ImgVO> selectImgPage(IPage<ImgVO> page, ImgVO img) {
		return page.setRecords(baseMapper.selectImgPage(page, img));
	}

	@SneakyThrows
	@Override
	public Img upload(String pictureSortId, MultipartFile imgFile) {
		String type = imgFile.getContentType();
		if (!CommonConstant.SUFFIXES.contains(type)) {
			throw new MsgException(CodeMsg.MANAGE_IMG_TYPE_ERROR.getCode(), CodeMsg.MANAGE_IMG_TYPE_ERROR.getMsg());
		}
		OssFile ossFile = null;
		try {
			ossFile = CompletableFuture.supplyAsync(() -> {
				R<OssFile> ossFileR = resourceService.upload(imgFile);
				if (!ossFileR.isSuccess()) {
					return null;
				}
				return ossFileR.getData();
			}, executor).get();
		} catch (InterruptedException | ExecutionException e) {
			e.printStackTrace();
		}
		if (ossFile == null) {
			return null;
		}
		Img img = new Img();
		img.setImgPath(ossFile.getLink());
		img.setImgCategoryId(pictureSortId);
		img.setStatus(1);
		this.save(img);
		return img;
	}

	@Override
	public MinioPolicy getPolicy(String pictureSortId, String fileName, String contentType) {
		R<MinioPolicy> minioPolicyR = resourceService.getPolicy(fileName, contentType);
		if (!minioPolicyR.isSuccess()) {
			return null;
		}
		MinioPolicy minioPolicy = minioPolicyR.getData();
		Img img = new Img();
		img.setImgPath(minioPolicy.getPostUrl() + "/" + minioPolicy.getKey());
		img.setImgCategoryId(pictureSortId);
		img.setStatus(1);
		this.save(img);
		minioPolicy.setId(img.getId());
		return minioPolicy;
	}

	@Override
	public IPage<Img> list(String id, Query query) {
		LambdaQueryWrapper<Img> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(Img::getImgCategoryId, id);
		return this.page(new Page<>(query.getCurrent(), query.getSize()), wrapper);
	}

	@SneakyThrows
	@Override
	public void delete(String id) {
		Img img = this.getById(id);
		String match = "img/";
		String filePath = match + img.getImgPath().split(match)[1];
		R delete = resourceService.delete(filePath);
		if (delete.isSuccess()) {
			this.removeById(id);
		}
		throw new MsgException(CodeMsg.MANAGE_IMG_DELETE_ERROR.getCode(), CodeMsg.MANAGE_IMG_DELETE_ERROR.getMsg());
	}

	@SneakyThrows
	@Override
	public void deletes(List<String> ids) {
		String match = "img/";
		List<Img> imgs = this.listByIds(ids);
		List<String> filePaths = imgs.stream().map(v -> match + v.getImgPath().split(match)[1]).collect(Collectors.toList());
		R deletes = resourceService.deletes(filePaths);
		if (deletes.isSuccess()) {
			this.removeByIds(ids);
		}
		throw new MsgException(CodeMsg.MANAGE_IMG_DELETE_ERROR.getCode(), CodeMsg.MANAGE_IMG_DELETE_ERROR.getMsg());
	}
}
